/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.ainlolcat.ainscience.project;

import org.ainlolcat.Variable;
import org.ainlolcat.ainscience.entity.Entity;
import org.ainlolcat.ainscience.metaentity.MetaEntity;
import org.ainlolcat.ainscience.templates.Template;

import java.util.*;

/**
 *
 * @author ain
 */
public class Project {
    private Map<String, Variable> variables = new TreeMap<String, Variable>();

    private Map<String, Entity> entities = new TreeMap<String, Entity>();

    private Map<String, MetaEntity> metaEntities = new TreeMap<String, MetaEntity>();

    private Map<String, Template> templates = new TreeMap<String, Template>();

    private Map<String, Template> externalTemplates = new TreeMap<String, Template>();

    private String homeDir="./";

    public String getHomeDir(){
        return homeDir;
    }

    public Project(String homeDir){
        this.homeDir = homeDir;
    }

    public void addVariable(Variable variable){
        variables.put(variable.getName(), variable);
    }

    public Variable getVariable(String name){
        return variables.get(name);
    }

    public Collection<Variable> getVariables(){
        return variables.values();
    }

    public void addExternalTemplate(Template temp){
        externalTemplates.put(temp.getName(), temp);
    }

    public void addTemplate(Template temp){
        templates.put(temp.getName(), temp);
    }

    public Template getTemplateByName(String name){
        return templates.get(name) != null ? templates.get(name) : externalTemplates.get(name);
    }

    public Set<String> getTemplateNames(){
        return templates.keySet();
    }

    public void addEntity(Entity entity){
        entities.put(entity.getName(), entity);
    }

    public void removeEntity(Entity ent){
        entities.remove(ent.getName());
    }
    
    public Entity getEntityByName(String name){
        return entities.get(name);
    }

    public List<Entity> getEntitiesByType(String type){
        List<Entity> answer = new ArrayList<Entity>();
        for (Entity ent:entities.values()){
            if (ent.getType().equals(type)){
                answer.add(ent);
            }
        }
        return answer;
    }

    public Set<String> getEntityNames(){
        return entities.keySet();
    }

    public Set<String> getFilteredEntityNames(boolean or, Filter... fs){
        if (fs==null||fs.length==0) return getEntityNames();
        Set<String> names = new LinkedHashSet<String>();
        for (Entity e:entities.values())
        {
            boolean isAccepted = fs[0].isAccepted(e);
            for (Filter f:fs){
                isAccepted = or?isAccepted||f.isAccepted(e):isAccepted&&f.isAccepted(e);
            }
            if (isAccepted) names.add(e.getName());
        }
        return names;
    }
    
    public Set<String> getFilteredEntityNames(Filter... fs){
        return getFilteredEntityNames(false,fs);
    }


    public void addMetaEntity(MetaEntity entity){
        metaEntities.put(entity.getName(), entity);
    }

    public MetaEntity getMetaEntityByName(String name){
        return metaEntities.get(name);
    }

    public List<MetaEntity> getMetaEntitiesByType(String type){
        List<MetaEntity> answer = new ArrayList<MetaEntity>();
        for (MetaEntity ent:metaEntities.values()){
            if (ent.getType().equals(type)){
                answer.add(ent);
            }
        }
        return answer;
    }

    public Set<String> getMetaEntityNames(){
        return metaEntities.keySet();
    }
}
